package com.simtop.util.worldUtil;

import com.simtop.service.impl.JwtLoginServiceImpl;
import freemarker.core.ParseException;
import freemarker.template.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Encoder;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName: WordDoc
 * @Description TODO word工具类
 * @Author liuzhaobo
 * @Date 2022/11/16 0016 9:23
 * @Version 1.0
 **/
public class WordDoc  {
    Logger logger = LoggerFactory.getLogger(Exception.class);

    private Configuration config = null;

    public WordDoc() {
        //版本选择，不要低于2.3的2.3以下的可能会有问题
        config = new Configuration(Configuration.VERSION_2_3_30);
        config.setDefaultEncoding("utf-8");
    }

    /**
     * @Author: liuzhaobo
     * @Description: freemarker 生成 word
     * @DateTime: 2022/11/16 0016 9:25
     * @Params:
     * @Return
     */
    public void createWord(Map<String, Object> dataMap, String templateName, String saveFilePath) {
        //加载模板(路径)数据
       // config.setClassForTemplateLoading(this.getClass(), "");
        //config加载模板数据的方法有三种，这边用的是通过文件路劲的方式 也是比较好的，因为模板文件你可以指定的放在服务器的某个文件夹下 不会乱。这里是放在项目的templates下的为了写demo方便的。
       // String path = Thread.currentThread().getContextClassLoader().getResource("").getPath() + "templates";
String path = "C:\\Users\\Administrator\\Desktop\\形拓题库系统\\questionbank\\target\\classes\\templates";
        System.out.println(path);
        try {
            config.setDirectoryForTemplateLoading(new File(path));
        } catch (IOException e) {
            e.printStackTrace();
        }
        //设置异常处理器 这样的话 即使没有属性也不会出错 如：${list.name}...不会报错
        config.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
        Template template = null;

        Writer out = null;
        FileOutputStream fos = null;

        try {
            template = config.getTemplate(templateName);
            File outFile = new File(saveFilePath);
            if (!outFile.getParentFile().exists()) {
                outFile.getParentFile().mkdirs();
            }
            fos = new FileOutputStream(outFile);
            out = new BufferedWriter(new OutputStreamWriter(fos));
            //将模板中的预先的代码替换为数据
            template.process(dataMap, out);
        } catch (TemplateNotFoundException e) {
            logger.error("模板文件未找到", e);
            e.printStackTrace();
        } catch (MalformedTemplateNameException e) {
            logger.error("模板类型不正确", e);
            e.printStackTrace();
        } catch (ParseException e) {
            logger.error("解析模板出错，请检查模板格式", e);
            e.printStackTrace();
        } catch (IOException e) {
            logger.error("IO读取失败", e);
            e.printStackTrace();
        } catch (TemplateException e) {
            logger.error("填充模板时异常", e);
            e.printStackTrace();
        } catch (Exception e) {
            logger.error("下载错误", e);
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (Exception e) {
                logger.error("关闭流错误", e);
                e.printStackTrace();
            }
        }

        logger.info("由模板文件：" + templateName + ".ftl" + " 生成文件 ：" + saveFilePath + " 成功！！");

    }

    public String ImageToBase64ByOnline(String imgURL) {
        ByteArrayOutputStream data = new ByteArrayOutputStream();
        try {
            // 创建URL
            URL url = new URL(imgURL);
            byte[] by = new byte[1024];
            // 创建链接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5000);
            InputStream is = conn.getInputStream();
            // 将内容读取内存中
            int len = -1;
            while ((len = is.read(by)) != -1) {
                data.write(by, 0, len);
            }
            // 关闭流
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组Base64编码
        BASE64Encoder decoder = new BASE64Encoder();
        return replaceEnter(decoder.encode(data.toByteArray()));
    }

    /**
     * @Author: liuzhaobo
     * @Description: 获取 bate 64
     * @DateTime: 2022/11/16 0016 9:30
     * @Params:
     * @Return
     */
    public String getImageStr(String imgFile) {


        InputStream in = null;
        byte[] data = null;
        try {
            // 构造URLpng
            URL url = new URL(imgFile);
            // 打开连接
            URLConnection con = url.openConnection();
            // 输入流
            in = con.getInputStream();
//            in = new FileInputStream(imgFile);
        } catch (FileNotFoundException e) {
            logger.error("加载图片未找到", e);
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            data = new byte[in.available()];
            //注：FileInputStream.available()方法可以从输入流中阻断由下一个方法调用这个输入流中读取的剩余字节数
            in.read(data);
            in.close();
        } catch (IOException e) {
            logger.error("IO操作图片错误", e);
            e.printStackTrace();
        }
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);

    }


    public  String imageUrlToBase64(String imgUrl) {
        URL url = null;
        InputStream is = null;
        ByteArrayOutputStream outStream = null;
        HttpURLConnection httpUrl = null;

        try {
            url = new URL(imgUrl);
            httpUrl = (HttpURLConnection) url.openConnection();
            httpUrl.connect();
            httpUrl.getInputStream();

            is = httpUrl.getInputStream();
            outStream = new ByteArrayOutputStream();

            //创建一个Buffer字符串
            byte[] buffer = new byte[1024];
            //每次读取的字符串长度，如果为-1，代表全部读取完毕
            int len = 0;
            //使用输入流从buffer里把数据读取出来
            while( (len = is.read(buffer)) != -1 ){
                //用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
                outStream.write(buffer, 0, len);
            }

            // 对字节数组Base64编码
            return encode(outStream.toByteArray());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(is != null) {
                    is.close();
                }
                if(outStream != null) {
                    outStream.close();
                }
                if(httpUrl != null) {
                    httpUrl.disconnect();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return null;
    }
    /**
     * 图片转字符串
     * @param image 图片Buffer
     * @return Base64编码
     */
    public static String encode(byte[] image){
        BASE64Encoder decoder = new BASE64Encoder();
        return replaceEnter(decoder.encode(image));
    }
    /**
     * 字符替换
     * @param str 字符串
     * @return 替换后的字符串
     */
    public static String replaceEnter(String str){
        String reg ="[\n-\r]";
        Pattern p = Pattern.compile(reg);
        Matcher m = p.matcher(str);
        return m.replaceAll("");
    }


}
